//-------------------------------------------------------------------------------------------------
// <copyright file="MainForm.cs" company="OfficeClip LLC">
// Copyright (c) OfficeClip LLC.  All rights reserved.
// </copyright>
//-------------------------------------------------------------------------------------------------

namespace OfficeClip.OpenSource.StyleFix
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Security.AccessControl;
using System.Text;
using System.Windows.Forms;

////using OfficeClip.Tools.Utility;

    /// <summary>
    /// The main form
    /// </summary>
    public partial class MainForm : Form
    {
        private List<SAObject> lsab;
        private Configure configure;
        private Hashtable hashExcludeStyleCop;

        /// <summary>
        /// Initializes a new instance of the <see cref="MainForm"/> class.
        /// </summary>
        public MainForm()
        {
            this.InitializeComponent();
            if (!string.IsNullOrEmpty(this.txtFolder.Text = Properties.Settings.Default.Project))
            {
                this.PopulateFileListBox();
            }

            this.configure = new Configure();
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void BtnBrowse_Click(object sender, EventArgs e)
        {
            this.openFileDialog1.Filter = "C# Projects|*.csproj";
            System.Windows.Forms.DialogResult result = this.openFileDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                this.txtFolder.Text = Properties.Settings.Default.Project = this.openFileDialog1.FileName;
                Properties.Settings.Default.Save();
                this.PopulateFileListBox();
            }
        }

        private void PopulateFileListBox()
        {
            List<string> fileList = this.GetFiles(new DirectoryInfo(Path.GetDirectoryName(this.txtFolder.Text)));
            for (int i = 0; i < fileList.Count; i++)
            {
                if (!fileList[i].EndsWith("Designer.cs"))
                {
                    this.filesListBox.Items.Add(fileList[i]);
                }
            }

            // this.CheckListBox(filesListBox, true);
            // DeactivateCheckBoxes();
            // chkSelectAll.Checked = true;
            this.IndeterminateCheckBoxes();
        }

        private void CheckListBox(CheckedListBox checkListBox, bool isChecked)
        {
            for (int i = 0; i < checkListBox.Items.Count; i++)
            {
                if (checkListBox.GetItemCheckState(i) != CheckState.Indeterminate)
                {
                    checkListBox.SetItemChecked(i, isChecked);
                }
            }
        }

        private List<string> GetFiles(DirectoryInfo dir)
        {
            List<string> fileList = new List<string>();
            foreach (FileInfo fi in dir.GetFiles("*.cs"))
            {
                fileList.Add(fi.FullName);
            }

            foreach (DirectoryInfo di in dir.GetDirectories())
            {
                foreach (string fileStr in this.GetFiles(di))
                {
                    fileList.Add(fileStr);
                }
            }

            return fileList;
        }

        private string GetInputString(string projectFileName)
        {
            Utility p = new Utility();
            string dir = System.Environment.GetEnvironmentVariable("SystemRoot") +
                         @"\Microsoft.Net\Framework\v2.0.50727";
            p.Run(
                dir,
				"msbuild.exe ",
                "\"" + projectFileName + "\" /t:StyleCop /p:MSBuildToolsPath=" + dir,
                true);
            if (p.Output.IndexOf("Build Failed") > -1)
            {
                this.txtOutput.Text += "Build Failed.";
                return string.Empty;
            }

            this.txtOutput.Text += "Build Succeeded.";
            this.txtOutput.Text += System.Environment.NewLine;
            Application.DoEvents();
            return p.Output;
        }

        private void BtnProcess_Click(object sender, EventArgs e)
        {
            btnEnable_Click(sender, e);
            List<string> outputString = new List<string>();

            string inputString = this.GetInputString(this.txtFolder.Text);
            string inputStr;

            // Separate the strings in its own list
            StringReader sr = new StringReader(inputString);
            while ((inputStr = sr.ReadLine()) != null)
            {
                outputString.Add(inputStr.Trim());
            }

            outputString.Sort();
            sr.Close();

            string[] parts;
            this.lsab = new List<SAObject>();
            string previousFileName = string.Empty;
            SAObject sab;
            string fileName;
            int violationFound = 0;
            int violationFixed = 0;
            int row, pos;
            string previousLine = string.Empty;
            foreach (string input in outputString)
            {
                if (input == previousLine)
                {
                    continue;
                }

                previousLine = input;
                parts = input.Split(":".ToCharArray());
                if ((parts.Length > 3) && parts[2].Trim().StartsWith("SA"))
                {
                    violationFound++;
                    if (this.configure.IsSAAllowed(parts[2].Trim()))
                    {
                        violationFixed++;
                        pos = parts[0].IndexOf("(");
                        fileName = parts[0].Substring(0, pos).Trim();
                        if ((fileName != previousFileName) && (previousFileName != string.Empty))
                        {
                            // Process the file
                            this.ProcessFile(previousFileName, violationFound, violationFixed);
                            this.lsab = new List<SAObject>();
                            Application.DoEvents();
                            violationFound = 0;
                            violationFixed = 0;
                        }

                        row = Convert.ToInt32(parts[0].Substring(pos + 1, parts[0].IndexOf(",") - pos - 1));
                        sab = new SAObject(fileName, parts[2].Trim(), row, parts[3].Trim());
                        this.lsab.Add(sab);
                        previousFileName = fileName;
                    }
                }
            }

            if (this.lsab.Count > 0)
            {
                this.ProcessFile(previousFileName, violationFound, violationFixed);
                 Application.DoEvents();
            }
        }

        private void ProcessFile(string fileName, int violationFound, int violationFixed)
        {
            // First check if this file is selected
            bool isSelected = false;
            string filePath = new DirectoryInfo(Path.GetDirectoryName(this.txtFolder.Text)) + @"\" + fileName;
            for (int i = 0; i < this.filesListBox.Items.Count; i++)
            {
                if (
                    (((string)this.filesListBox.Items[i]).ToLower() == filePath.ToLower()) &&
                    this.filesListBox.GetItemChecked(i))
                {
                    isSelected = true;
                    break;
                }
            }

            if (!isSelected)
            {
                return;
            }

            string strText = string.Empty;
            if (File.Exists(filePath))
            {
                StreamReader sr = new StreamReader(File.OpenRead(filePath));
                strText = sr.ReadToEnd();
                sr.Close();
            }

            StyleFix styleFix = new StyleFix(strText, this.lsab, fileName);
            StreamWriter writer = File.CreateText(filePath);
            writer.Write(styleFix.OutputFileContent());
            writer.Close();
            this.txtOutput.Text += string.Format(
               "File: {0}, Found: {1}, Fixed: {2}{3}",
               fileName,
               violationFound,
               violationFixed,
               System.Environment.NewLine);
        }

        private void chkSelectAll_CheckedChanged(object sender, EventArgs e)
        {
            this.CheckListBox(this.filesListBox, this.chkSelectAll.Checked);
        }

        private void btnEnable_Click(object sender, EventArgs e)
        {
            string str;
            this.Cursor = System.Windows.Forms.Cursors.WaitCursor;
            for (int i = 0; i < this.filesListBox.Items.Count; i++)
            {
                if (this.filesListBox.GetItemCheckState(i) == CheckState.Checked)
                {
                    str = Enable.ModifyProjectFile(this.txtFolder.Text, (string) this.filesListBox.Items[i], false);
                    this.txtOutput.Text += str + " Added: " + (string) this.filesListBox.Items[i] + System.Environment.NewLine;
                }
            }

            this.IndeterminateCheckBoxes();
            this.Cursor = System.Windows.Forms.Cursors.Default;

        }

        private void btnDisable_Click(object sender, EventArgs e)
        {
            string str;
            this.Cursor = System.Windows.Forms.Cursors.WaitCursor;
            for (int i = 0; i < this.filesListBox.Items.Count; i++)
            {
                if (this.filesListBox.GetItemChecked(i))
                {
                    str = Enable.ModifyProjectFile(this.txtFolder.Text, (string)this.filesListBox.Items[i], true);
                    this.txtOutput.Text += str + " Removed: " + (string)this.filesListBox.Items[i] + System.Environment.NewLine;
                }
            }

            this.IndeterminateCheckBoxes();
            this.Cursor = System.Windows.Forms.Cursors.Default;
        }

        private void btnConfigure_Click(object sender, EventArgs e)
        {
            this.configure.ShowDialog();
        }

        // private void button2_Click(object sender, EventArgs e)
        // {
        //    Enable.GetStyleCopStatus(txtFolder.Text, out hashExcludeStyleCop);
        // }
        private void IndeterminateCheckBoxes()
        {
            Enable.GetStyleCopStatus(this.txtFolder.Text, out this.hashExcludeStyleCop);
            for (int i = 0; i < this.filesListBox.Items.Count; i++)
            {
                string fileListEntry = (string)this.filesListBox.Items[i];
                string projectFolder = Path.GetDirectoryName(this.txtFolder.Text) + @"\";
                string fileName = fileListEntry.Substring(projectFolder.Length);
                if (this.hashExcludeStyleCop[fileName.ToLower()] != null)
                {
                    if (!(bool)this.hashExcludeStyleCop[fileName.ToLower()])
                    {
                        this.filesListBox.SetItemCheckState(i, CheckState.Indeterminate);
                    }
                    else
                    {
                        this.filesListBox.SetItemCheckState(i, CheckState.Unchecked);
                    }
                }
                else
                {
                    this.txtOutput.Text += "*** File not in hashtable: " + fileName + "\r\n";
                }
            }
        }

        private void filesListBox_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            // if (e.CurrentValue == CheckState.Indeterminate)
            //    e.NewValue = e.CurrentValue;
        }
    }
}
